﻿using System;

namespace Gemli.Reflection
{
    /// <summary>
    /// Contains utility methods for comparing <see cref="System.Type"/> objects.
    /// </summary>
    public static class TypeInfo
    {
        /// <summary>
        /// Returns true if the two type objects are either the same or if
        /// the <paramref name="typeSubject"/> parameter inherits
        /// the <paramref name="consideredBaseType"/> parameter.
        /// </summary>
        /// <param name="typeSubject"></param>
        /// <param name="consideredBaseType"></param>
        /// <returns></returns>
        public static bool IsOrInherits(this Type typeSubject, Type consideredBaseType)
        {
            return consideredBaseType.IsAssignableFrom(typeSubject);
        }

        /// <summary>
        /// Returns true if the specified type is, for example, an int?, decimal?, or 
        /// other variation of <see cref="Nullable{T}"/>.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsNullableWrappedValueType(this Type type)
        {
            if (type.IsGenericType && type.GetGenericArguments().Length == 1)
            {
                var gp = type.GetGenericArguments()[0];
                if (typeof (Nullable<>).MakeGenericType(gp) == type)
                {
                    return true;
                }
            }
            return false;
        }
    }
}
